{
  "openapi": "3.1.0",
  "info": {
    "title": "公共API开放接口",
    "description": "通过 MoreLogin 开放 API 管理公共资源（代理、分组和标签）。\n\n**基础 URL**：`https://api.morelogin.com`\n\n通过 OAuth2 Bearer 令牌进行身份验证。详情请参阅 [身份验证](../Getting%20Started/authentication.md)。\n",
    "version": "2026-09-05"
  },
  "tags": [
    {
      "name": "Proxy Management",
      "description": "创建、更新、删除和查询代理配置"
    },
    {
      "name": "Group Management",
      "description": "创建、更新、删除和查询环境分组"
    },
    {
      "name": "Tag Management",
      "description": "创建、更新、删除和查询环境标签"
    },
    {
      "name": "Webhook Management",
      "description": "配置接收 Webhook 事件的团队回调地址"
    }
  ],
  "paths": {
    "/proxyInfo/page": {
      "post": {
        "summary": "获取代理列表",
        "deprecated": false,
        "description": "分页列出团队的代理配置。\n\n- **副作用**：无。只读。可带退避安全重试。\n- **说明**：普通成员看不到密码，云代理和动态代理的密码也不会返回。动态代理会出现在这里，但它们由别处管理，无法通过代理接口编辑。",
        "operationId": "queryProxyInfoPageUsingPOST",
        "tags": [
          "Proxy Management"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "pattern": "^\\d+$",
                    "description": "可选的代理 ID，用于精确匹配。64 位 ID 请以十进制字符串传入，避免精度丢失；不传时不按 ID 筛选。其他筛选条件和分页参数仍然生效。",
                    "example": "1800000000000101"
                  },
                  "pageNo": {
                    "type": "integer",
                    "description": "当前页码（从 1 开始）",
                    "example": 1
                  },
                  "pageSize": {
                    "type": "integer",
                    "description": "每页数量",
                    "example": 10
                  },
                  "isCloudPhoneProxy": {
                    "type": "boolean",
                    "description": "是否为云手机代理。\n- `true`：排除本地/私有 IP（如 127.0.0.1、360、pia、私有地址段）\n- `false`：返回所有代理\n",
                    "example": false
                  },
                  "proxyCategoryType": {
                    "type": "integer",
                    "description": "代理类型：\n- `1` = 云平台\n- `2` = 自有 IP\n",
                    "example": 2
                  },
                  "proxyIp": {
                    "type": "string",
                    "description": "按代理 IP 地址筛选（模糊匹配）",
                    "example": ""
                  },
                  "proxyName": {
                    "type": "string",
                    "description": "按代理名称筛选（模糊匹配）",
                    "example": ""
                  },
                  "proxyProviders": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    },
                    "description": "代理提供商 ID 列表。支持的值：\n- `0` = 无\n- `4` = Oxylabs\n- `5` = Proxys.io\n- `6` = GeoSurf\n- `7` = Luminati\n- `8` = Lumauto\n- `9` = Oxylabsauto\n- `10` = Trojan\n- `11` = Shadowsocks\n- `12` = vmess\n- `13` = ABCPROXY\n- `14` = LunaProxy\n- `15` = IPHTML\n- `16` = PiaProxy\n- `17` = 922S5\n",
                    "example": []
                  },
                  "proxyStatus": {
                    "type": "integer",
                    "description": "代理分配状态：\n- `0` = 正常\n- `1` = 未分配\n- `2` = 升级中\n- `3` = 已过期\n- `4` = 即将过期\n> 注意：自有代理始终使用状态 `1`。\n",
                    "example": 1
                  },
                  "proxyCheckStatus": {
                    "type": "integer",
                    "description": "代理健康检测状态：\n- `0` = 待检测\n- `1` = 成功\n- `2` = 失败\n- `3` = 未知错误\n",
                    "example": 1
                  },
                  "proxyTypes": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    },
                    "description": "代理协议类型：\n- `0` = HTTP\n- `1` = HTTPS\n- `2` = SOCKS5\n- `3` = SSH\n",
                    "example": []
                  }
                },
                "required": []
              },
              "example": {
                "id": "1800000000000101",
                "pageNo": 1,
                "pageSize": 10,
                "isCloudPhoneProxy": false,
                "proxyCategoryType": 2,
                "proxyIp": "",
                "proxyName": "",
                "proxyProviders": [],
                "proxyStatus": 1,
                "proxyCheckStatus": 1,
                "proxyTypes": []
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data.dataList` 是当前页的记录，无匹配结果时为空数组；`data.total`、`data.current`、`data.pages` 描述分页信息。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "返回结果码 0:正常 其他为异常",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "错误信息",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "current": {
                          "type": "string"
                        },
                        "dataList": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "expiryTime": {
                                "description": "过期时间",
                                "type": "string"
                              },
                              "id": {
                                "description": "主键 ID",
                                "type": "string"
                              },
                              "proxyCategoryType": {
                                "description": "代理类型 1:平台代理; 2:自有代理",
                                "type": "integer"
                              },
                              "proxyCheckStatus": {
                                "description": "检测状态 0-待检测 1-检测成功 2-检测失败 3-未知错误",
                                "type": "integer"
                              },
                              "state": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "代理所在州或省。优先返回出口 IP 探测地域，缺失时使用配置地域；可能为 null 或空字符串。",
                                "example": "California"
                              },
                              "city": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "代理所在城市。优先返回出口 IP 探测地域，缺失时使用配置地域；可能为 null 或空字符串。",
                                "example": "Los Angeles"
                              },
                              "proxyPort": {
                                "type": [
                                  "integer",
                                  "null"
                                ],
                                "format": "int32",
                                "description": "代理连接端口，不从代理名称推断；不可用时可能为 null。",
                                "example": 1080
                              },
                              "proxyIp": {
                                "description": "代理 IP",
                                "type": "string"
                              },
                              "exportIp": {
                                "description": "出口 IP",
                                "type": "string"
                              },
                              "countryCode": {
                                "description": "国家代码",
                                "type": "string"
                              },
                              "proxyName": {
                                "description": "代理名称",
                                "type": "string"
                              },
                              "proxyProvider": {
                                "description": "代理提供商：默认值 0 - 无 4-Oxylabs 5-Proxys.io 7-Luminati 8-Lumauto 9-Oxylabsauto 10-Trojan，11-Shadowsocks 13-ABCPROXY 14-LunaProxy 15-IPHTML 16-PiaProxy 17-922S5\n",
                                "type": "integer"
                              },
                              "proxyType": {
                                "description": "代理类型：0-http 1-https 2-socks5 3-ssh",
                                "type": "integer"
                              },
                              "username": {
                                "description": "代理用户名",
                                "type": "string"
                              },
                              "password": {
                                "description": "代理密码",
                                "type": "string"
                              },
                              "refreshUrl": {
                                "description": "代理刷新 URL",
                                "type": "string"
                              }
                            }
                          }
                        },
                        "pages": {
                          "type": "string"
                        },
                        "total": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "current",
                        "dataList",
                        "pages",
                        "total"
                      ]
                    },
                    "requestId": {
                      "description": "操作请求 ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": null,
                  "data": {
                    "current": "1",
                    "dataList": [
                      {
                        "expiryTime": "2026-09-01 12:00:00",
                        "id": "1673823102599682",
                        "proxyCategoryType": 1,
                        "proxyCheckStatus": 1,
                        "state": "California",
                        "city": "Los Angeles",
                        "proxyPort": 1080,
                        "proxyIp": "string",
                        "exportIp": "9222",
                        "countryCode": "string",
                        "proxyName": "example-name",
                        "proxyProvider": 1,
                        "proxyType": 1,
                        "username": "example-name",
                        "password": "string",
                        "refreshUrl": "https://example.com/resource"
                      }
                    ],
                    "pages": "1",
                    "total": "1"
                  },
                  "requestId": "0d8b6f1c-9f4e-4d02-9d1a-7c3f5a1b2c3d"
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/proxyInfo/add": {
      "post": {
        "summary": "添加代理",
        "deprecated": false,
        "description": "在团队中创建一条代理配置。\n\n- **前置条件**：`proxyPort` 必填且必须在 1–65535 之间，`proxyProvider` 必须是已识别的设备服务。\n- **副作用**：写入一条代理记录并返回其 ID，可直接用于绑定浏览器。不会向代理类型发送任何请求。\n- **完成信号**：同步。\n- **重试**：**不做名称或配置的唯一性校验。** 同一个请求体提交两次会产生两条代理、两个 ID。超时后请先在 `/proxyInfo/page` 中检索，再决定是否重发。\n\n已记录的业务错误码：`14023`。 各错误码的含义见 [Error Codes](../Getting%20Started/error-codes.md)。任何接口还可能返回通用错误码。",
        "operationId": "addUsingPOST",
        "tags": [
          "Proxy Management"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "city": {
                    "type": "string",
                    "description": "城市",
                    "example": ""
                  },
                  "country": {
                    "type": "string",
                    "description": "国家代码（ISO 3166-1 alpha-2）。仅当 proxyProvider=17 时必填。\n",
                    "example": "AD"
                  },
                  "encryptionType": {
                    "type": "integer",
                    "format": "int32",
                    "description": "加密类型，有效值为 1 到 14 的整数。",
                    "example": 14
                  },
                  "ipChangeAction": {
                    "type": "integer",
                    "format": "int32",
                    "description": "IP 变更时的操作：0 = 阻止，1 = 警告",
                    "example": 1
                  },
                  "ipMonitor": {
                    "type": "boolean",
                    "description": "启用 IP 变更监控",
                    "example": false
                  },
                  "password": {
                    "type": "string",
                    "description": "代理认证密码",
                    "example": ""
                  },
                  "proxyIp": {
                    "type": "string",
                    "description": "代理 IP 地址",
                    "example": "8.10.22.46"
                  },
                  "proxyName": {
                    "type": "string",
                    "description": "代理名称（支持占位符如 {{random}}）",
                    "example": "sock5_{{random}}"
                  },
                  "proxyPort": {
                    "type": "integer",
                    "format": "int32",
                    "description": "代理端口号",
                    "example": 65534
                  },
                  "proxyProvider": {
                    "type": "integer",
                    "format": "int32",
                    "description": "代理类型：\n0=HTTP，1=HTTPS，2=SOCKS5，3=SSH，4=Oxylabs，5=Proxys.io，6=GeoSurf，7=Luminati，8=Lumauto，9=Oxylabsauto，10=Trojan，11=Shadowsocks，12=vmess，13=ABCPROXY，14=LunaProxy，15=IPHTML，16=PiaProxy，17=922S5。\n特殊规则：\n- proxyProvider 为 7 或 8 时，proxyType 必填。\n- proxyProvider 为 17 时，country 必填；state 和 city 可选。",
                    "example": 2
                  },
                  "proxyType": {
                    "type": "integer",
                    "format": "int32",
                    "description": "代理协议类型：0=HTTP，1=HTTPS，2=SOCKS5，3=SSH。\n仅当 proxyProvider 为 7 或 8 时必填。",
                    "example": 1
                  },
                  "refreshUrl": {
                    "type": "string",
                    "description": "刷新动态代理 IP 的 URL（如果提供商支持）",
                    "example": ""
                  },
                  "state": {
                    "type": "string",
                    "description": "省份",
                    "example": ""
                  },
                  "username": {
                    "type": "string",
                    "description": "代理认证用户名",
                    "example": ""
                  }
                },
                "required": [
                  "proxyIp",
                  "proxyPort",
                  "proxyProvider"
                ]
              },
              "example": {
                "proxyIp": "8.10.22.46",
                "proxyPort": 65534,
                "proxyProvider": 2,
                "proxyType": 1,
                "country": "AD",
                "state": "",
                "city": "",
                "encryptionType": 14,
                "ipChangeAction": 1,
                "ipMonitor": false,
                "proxyName": "sock5_{{random}}",
                "refreshUrl": "",
                "username": "",
                "password": ""
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data` 是单个整数值。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "返回结果码 0:正常 其他为异常",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "错误信息",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "description": "代理 ID",
                      "type": "integer"
                    },
                    "requestId": {
                      "description": "操作请求 ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": 0,
                  "requestId": "abcd1234"
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/proxyInfo/update": {
      "post": {
        "summary": "修改代理信息",
        "deprecated": false,
        "description": "更新一条代理配置。\n\n- **前置条件**：代理必须存在于团队中。**动态代理不能通过本接口更新。** 设备服务必须是已识别的取值。\n- **副作用**：这是整体覆盖而非局部更新——你省略的字段会回落到默认值，而不是保留当前值。请先读出该代理再完整回传。\n- **生效范围**：浏览器的绑定关系保持不变（因为只有代理记录本身发生变化），但已在运行的浏览器或云手机会继续使用它们启动时的连接信息。请重启它们以采用新配置。\n- **完成信号**：同步。没有乐观锁，并发更新是后写覆盖。\n\n已记录的业务错误码：`14003`, `14023`。 各错误码的含义见 [Error Codes](../Getting%20Started/error-codes.md)。任何接口还可能返回通用错误码。",
        "operationId": "updateProxyUsingPOST",
        "tags": [
          "Proxy Management"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "id",
                  "proxyIp",
                  "proxyPort",
                  "proxyProvider"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "代理唯一 ID"
                  },
                  "proxyIp": {
                    "type": "string",
                    "description": "代理服务器 IP 地址"
                  },
                  "proxyPort": {
                    "type": "integer",
                    "description": "代理服务器端口"
                  },
                  "proxyName": {
                    "type": "string",
                    "description": "代理自定义名称"
                  },
                  "country": {
                    "type": "string",
                    "description": "国家（如 \"US\"、\"CN\"）"
                  },
                  "city": {
                    "type": "string",
                    "description": "城市名称"
                  },
                  "username": {
                    "type": "string",
                    "description": "认证用户名（如需要）"
                  },
                  "password": {
                    "type": "string",
                    "description": "认证密码（如需要）"
                  },
                  "proxyType": {
                    "type": "integer",
                    "description": "代理协议类型：\n- `0` = HTTP\n- `1` = HTTPS\n- `2` = SOCKS5\n- `3` = SSH"
                  },
                  "proxyProvider": {
                    "type": "integer",
                    "description": "代理类型 ID：\n- `0` = HTTP\n- `1` = HTTPS\n- `2` = SOCKS5\n- `3` = SSH\n- `4` = Oxylabs\n- `5` = Proxys.io\n- `6` = GeoSurf\n- `7` = Luminati\n- `8` = Lumauto\n- `9` = Oxylabsauto\n- `10` = Trojan\n- `11` = Shadowsocks\n- `12` = vmess\n- `13` = ABCPROXY\n- `14` = LunaProxy\n- `15` = IPHTML\n- `16` = PiaProxy\n- `17` = 922S5"
                  },
                  "encryptionType": {
                    "type": "integer",
                    "description": "加密类型（提供商特定，通常 0 为明文）"
                  },
                  "ipMonitor": {
                    "type": "boolean",
                    "description": "启用 IP 变更监控"
                  },
                  "ipChangeAction": {
                    "type": "integer",
                    "description": "IP 变化时的动作：\n- `1` = 通知 / 刷新（常用值）\n> 完整取值请查阅系统文档。"
                  },
                  "refreshUrl": {
                    "type": "string",
                    "description": "触发 IP 刷新的 URL（如果提供商支持）"
                  },
                  "state": {
                    "type": "string",
                    "description": "保留字段或自定义状态（可选）"
                  }
                }
              },
              "example": {
                "id": "1566403036579198",
                "proxyIp": "108.11.23.85",
                "proxyPort": 4096,
                "proxyName": "MyProxy",
                "country": "US",
                "city": "New York",
                "username": "",
                "password": "",
                "proxyType": 0,
                "proxyProvider": 0,
                "encryptionType": 0,
                "ipMonitor": true,
                "ipChangeAction": 1,
                "refreshUrl": "",
                "state": ""
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。该接口不返回响应载荷，结果由 `code` 表达。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "返回结果码 0:正常 其他为异常",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "错误信息",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "requestId": {
                      "description": "操作请求 ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "requestId": "efgh5678"
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/proxyInfo/delete": {
      "post": {
        "summary": "删除代理",
        "deprecated": false,
        "description": "删除一条或多条代理配置。\n\n- **前置条件**：至少有一个 ID 能在团队中解析；解析不到的会被静默忽略。**未过期的云平台代理不可删除**，会返回专门的错误码。\n- **副作用**：自有代理会被移除并解除跳板机绑定。已过期的云平台代理改为标记待释放、取消其订阅，并**异步**释放 IP——响应返回时释放可能仍在进行中。\n- **级联影响**：绑定了该代理的浏览器与云手机**既不会被阻止删除，也不会被解绑**。它们仍指向已删除的代理，运行中的会话不会被中断。删除前请先用 `/env/setProxy/batch` 改绑。\n- **重试**：ID 逐个处理，遇到第一个被拒即中止，因此批量可能部分生效。重试前请重新读取 `/proxyInfo/page`。\n\n已记录的业务错误码：`14017`, `14024`。 各错误码的含义见 [Error Codes](../Getting%20Started/error-codes.md)。任何接口还可能返回通用错误码。",
        "operationId": "deleteProxyUsingPOST",
        "tags": [
          "Proxy Management"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int64"
                }
              },
              "example": [
                1054661322597744600,
                1054661322597744600
              ]
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。该接口不返回响应载荷，结果由 `code` 表达。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "返回结果码 0:正常 其他为异常",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "错误信息",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "requestId": {
                      "description": "操作请求 ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "requestId": "ijkl9012"
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/envgroup/page": {
      "post": {
        "operationId": "envgroupPagePost",
        "summary": "获取分组列表",
        "deprecated": false,
        "description": "分页列出浏览器分组。\n\n- **副作用**：无。只读。可带退避安全重试。\n- **说明**：当团队按分组授权时，没有任何分组授权的成员会收到空页而不是报错。",
        "tags": [
          "Group Management"
        ],
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "groupName": {
                    "type": "string",
                    "title": "分组名称（模糊匹配）"
                  },
                  "pageNo": {
                    "type": "integer",
                    "title": "当前页码"
                  },
                  "pageSize": {
                    "type": "integer",
                    "title": "每页数量"
                  }
                },
                "required": [
                  "groupName",
                  "pageNo",
                  "pageSize"
                ]
              },
              "example": {
                "groupName": "132-kernel",
                "pageNo": 1,
                "pageSize": 10
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data.dataList` 是当前页的记录，无匹配结果时为空数组；`data.total`、`data.current`、`data.pages` 描述分页信息。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "返回结果码 0:正常 其他为异常",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "错误信息",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "current": {
                          "type": "string"
                        },
                        "dataList": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "description": "分组 ID",
                                "type": "string"
                              },
                              "groupName": {
                                "description": "分组名称",
                                "type": "string"
                              }
                            }
                          }
                        },
                        "pages": {
                          "type": "string"
                        },
                        "total": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "current",
                        "dataList",
                        "pages",
                        "total"
                      ]
                    },
                    "requestId": {
                      "description": "操作请求 ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": {
                    "current": "0",
                    "dataList": [
                      {
                        "id": "0",
                        "groupName": ""
                      }
                    ],
                    "pages": "0",
                    "total": "0"
                  },
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/envgroup/edit": {
      "post": {
        "operationId": "envgroupEditPost",
        "summary": "修改分组信息",
        "deprecated": false,
        "description": "重命名一个浏览器分组。\n\n- **前置条件**：分组必须存在于团队中，调用者对它有权限，且新名称不能与其他分组冲突。只有名称确实发生变化时才会做唯一性校验。\n- **副作用**：重命名分组。浏览器仍留在其中——它们通过 ID 引用分组，因此不需要更新其他任何东西。\n- **完成信号**：同步且幂等。",
        "tags": [
          "Group Management"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "groupName",
                  "id"
                ],
                "properties": {
                  "groupName": {
                    "type": "string",
                    "description": "环境分组的新名称"
                  },
                  "id": {
                    "type": "string",
                    "description": "要更新的分组唯一 ID"
                  }
                }
              },
              "example": {
                "groupName": "Group-1574544945848579",
                "id": "1574525425557584"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data` 是单个布尔值。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "返回结果码 0:正常 其他为异常",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "错误信息",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "boolean",
                      "description": "操作结果"
                    },
                    "requestId": {
                      "description": "操作请求 ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": null,
                  "data": true,
                  "requestId": "0d8b6f1c-9f4e-4d02-9d1a-7c3f5a1b2c3d"
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/envgroup/create": {
      "post": {
        "operationId": "envgroupCreatePost",
        "summary": "添加分组",
        "deprecated": false,
        "description": "创建一个浏览器分组。\n\n- **前置条件**：名称不能为空、不超过 100 字符，且不能与团队中已有分组重名。**一个团队最多 1000 个分组。**\n- **副作用**：创建分组。当团队按分组授权且调用者不是所有者时，调用者也会被授予该新分组的访问权限。\n- **完成信号**：同步；`data` 携带新分组 ID。\n- **重试**：重名会被拒绝而不是复用已有分组，因此在「实际成功但你没收到响应」之后重试会得到重名错误——这本身就是第一次已成功的信号。请用 `/envgroup/page` 确认。",
        "tags": [
          "Group Management"
        ],
        "parameters": [],
        "security": [
          {
            "Authorization": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {}
              },
              "example": {}
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data` 是对象，包含字段 `id`、`groupName`。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "返回结果码 0:正常 其他为异常",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "错误信息",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "description": "操作返回的数据",
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "分组 ID",
                          "type": "string"
                        },
                        "groupName": {
                          "description": "分组名称",
                          "type": "string"
                        }
                      }
                    },
                    "requestId": {
                      "description": "操作请求 ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": null,
                  "data": {
                    "id": "1673823102599682",
                    "groupName": "example-name"
                  },
                  "requestId": "0d8b6f1c-9f4e-4d02-9d1a-7c3f5a1b2c3d"
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/envgroup/delete": {
      "post": {
        "operationId": "envgroupDeletePost",
        "summary": "删除分组",
        "deprecated": false,
        "description": "删除一个或多个浏览器分组。\n\n- **前置条件**：至少有一个 ID 能在团队中解析且调用者对它有权限；解析不到的 ID 会被静默忽略。\n- **副作用**：删除分组及其成员授权关系。原本在分组内的浏览器与云手机变为未分组，因此不会留下悬空的分组引用。若打开「同时删除环境」开关，还会把你有权限的浏览器**移入回收站**——它们不会被销毁，且该开关对云手机始终无效。\n- **完成信号**：同步但**非原子**。分组先被删除，后续步骤仍可能失败（例如浏览器正在运行或处于转移中），结果是分组已消失而浏览器未被移动。\n- **重试**：重试前请用 `/envgroup/page` 和浏览器列表核实。\n\n已记录的业务错误码：`19064`。 各错误码的含义见 [Error Codes](../Getting%20Started/error-codes.md)。任何接口还可能返回通用错误码。",
        "tags": [
          "Group Management"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "ids"
                ],
                "properties": {
                  "ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "要删除的分组唯一 ID"
                  },
                  "isDeleteAllEnv": {
                    "type": "boolean",
                    "description": "是否删除分组内的环境？false:不删除 true:删除"
                  }
                }
              },
              "example": {
                "ids": [
                  "string"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data` 是单个布尔值。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "返回结果码 0:正常 其他为异常",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "错误信息",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "description": "操作请求 ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": true,
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/envtag/all": {
      "get": {
        "operationId": "envtagAllGet",
        "summary": "获取标签列表",
        "deprecated": false,
        "description": "返回团队内所有浏览器标签。\n\n- **副作用**：无。只读。可带退避安全重试。\n- **说明**：本接口**不分页，且标签没有服务端数量上限**，因此响应体会随团队创建的标签数增长。请相应地设计客户端。",
        "tags": [
          "Tag Management"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "成功。`data` 是对象数组，元素包含字段 `id`、`tagName`；无数据时返回空数组。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "返回结果码 0:正常 其他为异常",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "错误信息",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "标签 ID",
                            "type": "string"
                          },
                          "tagName": {
                            "description": "标签名称",
                            "type": "string"
                          }
                        }
                      }
                    },
                    "requestId": {
                      "description": "操作请求 ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": [
                    {
                      "id": "0",
                      "tagName": ""
                    }
                  ],
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/envtag/create": {
      "post": {
        "operationId": "envtagCreatePost",
        "summary": "创建标签",
        "deprecated": false,
        "description": "创建一个浏览器标签。\n\n- **前置条件**：名称不能为空、不超过 100 字符，且不能与团队中已有标签重名。\n- **副作用**：创建标签并返回其 ID。与分组不同，标签没有数量上限。\n- **重试**：重名会被拒绝而不是复用已有标签。请用 `/envtag/all` 确认。",
        "tags": [
          "Tag Management"
        ],
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "tagName": {
                    "type": "string",
                    "description": "标签名称"
                  }
                }
              },
              "example": {
                "tagName": "Tag-123"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data` 是对象，包含字段 `id`、`tagName`。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "返回结果码 0:正常 其他为异常",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "错误信息",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "标签 ID",
                          "type": "string"
                        },
                        "tagName": {
                          "description": "标签名称",
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "tagName"
                      ]
                    },
                    "requestId": {
                      "description": "操作请求 ID",
                      "type": "string"
                    },
                    "error": {
                      "type": "object",
                      "properties": {}
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": {
                    "id": "0",
                    "tagName": ""
                  },
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/envtag/edit": {
      "post": {
        "operationId": "envtagEditPost",
        "summary": "修改标签信息",
        "deprecated": false,
        "description": "重命名一个浏览器标签。\n\n- **前置条件**：标签必须存在于团队中，且新名称不能与其他标签冲突。\n- **副作用**：重命名标签。已有的标签挂载关系不受影响，浏览器会立即显示新名称。\n- **完成信号**：同步且幂等。",
        "tags": [
          "Tag Management"
        ],
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "标签 ID"
                  },
                  "tagName": {
                    "type": "string",
                    "description": "标签名称"
                  }
                }
              },
              "example": {
                "id": "1564715845550177",
                "tagName": "Updated-123"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data` 是单个布尔值。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "返回结果码 0:正常 其他为异常",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "错误信息",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "description": "操作请求 ID",
                      "type": "string"
                    },
                    "error": {
                      "type": "object",
                      "properties": {}
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": true,
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/envtag/delete": {
      "post": {
        "operationId": "envtagDeletePost",
        "summary": "删除标签",
        "deprecated": false,
        "description": "删除一个或多个浏览器标签。\n\n- **前置条件**：至少有一个 ID 能在团队中解析；解析不到的会被静默忽略。\n- **副作用**：删除标签。该标签会从所有携带它的浏览器上消失，且不会删除任何浏览器。本接口只管理浏览器标签——云存储文件标签另有接口。\n- **完成信号**：同步。重复调用会报标签无效，这说明第一次已成功。\n\n已记录的业务错误码：`19105`。 各错误码的含义见 [Error Codes](../Getting%20Started/error-codes.md)。任何接口还可能返回通用错误码。",
        "tags": [
          "Tag Management"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "ids"
                ],
                "properties": {
                  "ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "要删除的标签唯一 ID"
                  }
                }
              },
              "example": {
                "ids": [
                  "string"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data` 是单个布尔值。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "返回结果码 0:正常 其他为异常",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "错误信息",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "description": "操作请求 ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": true,
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/webhook/config": {
      "post": {
        "operationId": "webhookConfigPost",
        "summary": "配置团队 Webhook",
        "deprecated": false,
        "description": "新增或替换团队的 Webhook 配置。\n\n- **前置条件**：`callbackUrl` 必须是 1 到 1024 个字符的 HTTPS 地址，带主机名，不含用户信息与片段，端口合法。它解析到的每个地址都必须是公网可路由的；localhost、内网、链路本地、CGNAT、云元数据、协议保留、文档示例与 6to4 等范围会被拒绝。实际建连时会再校验一次，因此某个域名若之后解析到内网范围，只会导致该次投递失败，不会打到你的内网。\n- **副作用**：按服务端上下文所属团队做唯一配置的 upsert。`teamId` 不从请求读取，因此调用方无法配置其他团队。Local API 与 Open API 两个入口读写同一份记录，响应会回显已保存的内容。\n- **停用**：`enabled: false` 会保留地址并停止创建新事件。已排队的事件在下次被授权时若配置仍处于停用状态，会被逐条取消；因此快速重新启用可以让它们继续投递。\n- **重试**：安全。保存是按团队的 upsert，重复发送同一请求会收敛到同一状态。\n\n回调契约、事件名称与重试节奏见 [Webhooks](../Getting%20Started/webhooks.md)。\n\n已记录的业务错误码：`41001`。 各错误码的含义见 [Error Codes](../Getting%20Started/error-codes.md)。任何接口还可能返回通用错误码。",
        "tags": [
          "Webhook Management"
        ],
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "callbackUrl": {
                    "description": "接收事件的 HTTPS 地址。1 到 1024 个字符。",
                    "type": "string",
                    "maxLength": 1024
                  },
                  "enabled": {
                    "description": "该团队是否启用投递。",
                    "type": "boolean"
                  }
                },
                "required": [
                  "callbackUrl",
                  "enabled"
                ]
              },
              "example": {
                "callbackUrl": "https://example.com/morelogin/webhook",
                "enabled": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data` 是包含 `callbackUrl` 与 `enabled` 字段的对象，回显已保存的配置。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "返回结果码，0 表示正常，其他码为异常。",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "错误信息",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "callbackUrl": {
                          "description": "已保存的 HTTPS 回调地址。",
                          "type": "string"
                        },
                        "enabled": {
                          "description": "该团队是否启用投递。",
                          "type": "boolean"
                        }
                      }
                    },
                    "requestId": {
                      "description": "操作请求 ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": {
                    "callbackUrl": "https://example.com/morelogin/webhook",
                    "enabled": true
                  },
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        }
      }
    }
  },
  "webhooks": {
    "cloud_phone.power_on": {
      "post": {
        "operationId": "webhookCloudPhonePowerOn",
        "summary": "云手机开机完成",
        "description": "在开机得到最终结果后发送。\n\n只有当操作完成回调成功且本地同步已提交时，`success` 才为 `true`。开机计费失败，或异步代理检测失败并完成失败收尾时，都报告开机失败，且不会另外产生关机事件。安装预设应用等已推迟的后置任务不改变该结果。\n\n若开机过程被关机操作打断，本次尝试不产生开机事件；随后真正关机成功时仍会产生独立的 `cloud_phone.power_off`。",
        "tags": [
          "Webhook Management"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventId"
          },
          {
            "$ref": "#/components/parameters/WebhookEventType"
          },
          {
            "$ref": "#/components/parameters/WebhookUserAgent"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloudPhoneWebhookEvent"
              },
              "example": {
                "eventId": "c7f3a2b10d8e4f6a9c1b2d3e4f5a6b7c",
                "eventType": "cloud_phone.power_on",
                "eventTime": "1787241600000",
                "data": {
                  "teamId": "10001",
                  "cloudPhoneId": "20001"
                },
                "result": {
                  "success": false,
                  "code": "33318",
                  "message": "Operation failed"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "cloud_phone.power_off": {
      "post": {
        "operationId": "webhookCloudPhonePowerOff",
        "summary": "云手机已关机",
        "description": "在关机成功时发送。关机失败不会产生该事件，因此这里的 `result.success` 恒为 `true`。\n\n`data.reason` 记录关机原因。",
        "tags": [
          "Webhook Management"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventId"
          },
          {
            "$ref": "#/components/parameters/WebhookEventType"
          },
          {
            "$ref": "#/components/parameters/WebhookUserAgent"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloudPhonePowerOffWebhookEvent"
              },
              "example": {
                "eventId": "5b1d0c9e7a2f4d38b6c5a4e3f2d1c0b9",
                "eventType": "cloud_phone.power_off",
                "eventTime": "1787241600000",
                "data": {
                  "teamId": "10001",
                  "cloudPhoneId": "20001",
                  "reason": "MONEY_SAVING"
                },
                "result": {
                  "success": true,
                  "code": "0",
                  "message": null
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "cloud_phone.restart": {
      "post": {
        "operationId": "webhookCloudPhoneRestart",
        "summary": "云手机重启完成",
        "description": "在重启得到最终结果后发送。只有当操作完成回调成功且本地同步已提交时，`success` 才为 `true`。",
        "tags": [
          "Webhook Management"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventId"
          },
          {
            "$ref": "#/components/parameters/WebhookEventType"
          },
          {
            "$ref": "#/components/parameters/WebhookUserAgent"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloudPhoneWebhookEvent"
              },
              "example": {
                "eventId": "9e4c1a7b3f2d40518a6b5c4d3e2f1a0b",
                "eventType": "cloud_phone.restart",
                "eventTime": "1787241600000",
                "data": {
                  "teamId": "10001",
                  "cloudPhoneId": "20001"
                },
                "result": {
                  "success": true,
                  "code": "0",
                  "message": null
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "cloud_phone.reset": {
      "post": {
        "operationId": "webhookCloudPhoneReset",
        "summary": "云手机重置完成",
        "description": "在重置得到最终结果后发送。只有当操作完成回调成功且本地同步已提交时，`success` 才为 `true`。",
        "tags": [
          "Webhook Management"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventId"
          },
          {
            "$ref": "#/components/parameters/WebhookEventType"
          },
          {
            "$ref": "#/components/parameters/WebhookUserAgent"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloudPhoneWebhookEvent"
              },
              "example": {
                "eventId": "2f8a6d4c0b9e47138c7d6e5f4a3b2c1d",
                "eventType": "cloud_phone.reset",
                "eventTime": "1787241600000",
                "data": {
                  "teamId": "10001",
                  "cloudPhoneId": "20001"
                },
                "result": {
                  "success": true,
                  "code": "0",
                  "message": null
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "cloud_phone.new_machine": {
      "post": {
        "operationId": "webhookCloudPhoneNewMachine",
        "summary": "云手机一键新机完成",
        "description": "在一键新机操作得到最终结果后发送。只有当操作完成回调成功且本地同步已提交时，`success` 才为 `true`。",
        "tags": [
          "Webhook Management"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventId"
          },
          {
            "$ref": "#/components/parameters/WebhookEventType"
          },
          {
            "$ref": "#/components/parameters/WebhookUserAgent"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloudPhoneWebhookEvent"
              },
              "example": {
                "eventId": "7c3b1e9d5a4f42068b1c2d3e4f5a6b70",
                "eventType": "cloud_phone.new_machine",
                "eventTime": "1787241600000",
                "data": {
                  "teamId": "10001",
                  "cloudPhoneId": "20001"
                },
                "result": {
                  "success": true,
                  "code": "0",
                  "message": null
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "cloud_browser.start": {
      "post": {
        "operationId": "webhookCloudBrowserStart",
        "summary": "云浏览器开启完成",
        "description": "在云浏览器开启得到最终结果后发送。",
        "tags": [
          "Webhook Management"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventId"
          },
          {
            "$ref": "#/components/parameters/WebhookEventType"
          },
          {
            "$ref": "#/components/parameters/WebhookUserAgent"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloudBrowserWebhookEvent"
              },
              "example": {
                "eventId": "4a9f2c7e1b8d43509c6a5b4c3d2e1f00",
                "eventType": "cloud_browser.start",
                "eventTime": "1787241600000",
                "data": {
                  "teamId": "10001",
                  "cloudBrowserId": "30001",
                  "runId": "40001"
                },
                "result": {
                  "success": true,
                  "code": "0",
                  "message": null
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "cloud_browser.stop": {
      "post": {
        "operationId": "webhookCloudBrowserStop",
        "summary": "云浏览器关闭完成",
        "description": "云浏览器每次关闭尝试都会发送，无论成功与否。进入关闭失败状态本身就是该次尝试的失败结果；随后的人工重试或强制释放属于新操作，会产生新的 `eventId`。\n\n事件按关闭操作去重，因此同一次尝试不会产生两个事件，两次尝试也不会被合并。内部归档失败只影响 `result`，绝不覆盖关闭流程开始时固化的 `reason`。",
        "tags": [
          "Webhook Management"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventId"
          },
          {
            "$ref": "#/components/parameters/WebhookEventType"
          },
          {
            "$ref": "#/components/parameters/WebhookUserAgent"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloudBrowserStopWebhookEvent"
              },
              "example": {
                "eventId": "c7f3a2b10d8e4f6a9c1b2d3e4f5a6b7c",
                "eventType": "cloud_browser.stop",
                "eventTime": "1787241600000",
                "data": {
                  "teamId": "10001",
                  "cloudBrowserId": "30001",
                  "runId": "40001",
                  "reason": "BROWSER_EXITED"
                },
                "result": {
                  "success": false,
                  "code": "40006",
                  "message": "Operation failed"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "Authorization": {
        "type": "http",
        "description": "令牌取自请求访问令牌接口响应的 access_token 字段",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    },
    "parameters": {
      "WebhookEventId": {
        "name": "X-Webhook-Event-Id",
        "in": "header",
        "required": true,
        "description": "与正文中的 `eventId` 相同。用它让你的处理逻辑保持幂等。",
        "schema": {
          "type": "string"
        }
      },
      "WebhookEventType": {
        "name": "X-Webhook-Event-Type",
        "in": "header",
        "required": true,
        "description": "与正文中的 `eventType` 相同，便于不解析正文就完成路由。",
        "schema": {
          "type": "string"
        }
      },
      "WebhookUserAgent": {
        "name": "User-Agent",
        "in": "header",
        "required": true,
        "description": "固定为 `MoreLogin-Webhook/1.0`。",
        "schema": {
          "type": "string"
        }
      }
    },
    "responses": {
      "WebhookAck": {
        "description": "任何 2xx 都视为投递成功。响应正文会被忽略，所以请尽早返回并把实际处理放到异步。其他任何情况，包括连接超时和读取超时，都算失败并会重试。"
      }
    },
    "schemas": {
      "WebhookResult": {
        "type": "object",
        "description": "该事件所描述操作的最终结果。",
        "properties": {
          "success": {
            "description": "该操作最终是否成功。",
            "type": "boolean"
          },
          "code": {
            "description": "成功时为 `0`。失败时为稳定的、与语言无关的业务错误码。",
            "type": "string"
          },
          "message": {
            "description": "成功时为 `null`。失败时为按团队语言给出的说明；该语言或其文案缺失时降级为 `en-US`。",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "success",
          "code",
          "message"
        ]
      },
      "CloudPhoneWebhookEvent": {
        "type": "object",
        "properties": {
          "eventId": {
            "description": "唯一事件 ID。同一事件的投递重试与内部重放都复用它，因此请把它当作幂等键。",
            "type": "string"
          },
          "eventType": {
            "description": "稳定的事件名称。",
            "type": "string"
          },
          "eventTime": {
            "description": "业务最终结果发生的时间，Unix 毫秒时间戳。以字符串形式发送。",
            "type": "string"
          },
          "data": {
            "type": "object",
            "properties": {
              "teamId": {
                "description": "拥有该资源的团队。",
                "type": "string"
              },
              "cloudPhoneId": {
                "description": "该事件对应的云手机。",
                "type": "string"
              }
            },
            "required": [
              "teamId",
              "cloudPhoneId"
            ]
          },
          "result": {
            "$ref": "#/components/schemas/WebhookResult"
          }
        },
        "required": [
          "eventId",
          "eventType",
          "eventTime",
          "data",
          "result"
        ]
      },
      "CloudPhonePowerOffWebhookEvent": {
        "type": "object",
        "properties": {
          "eventId": {
            "description": "唯一事件 ID。同一事件的投递重试与内部重放都复用它，因此请把它当作幂等键。",
            "type": "string"
          },
          "eventType": {
            "description": "稳定的事件名称。",
            "type": "string"
          },
          "eventTime": {
            "description": "业务最终结果发生的时间，Unix 毫秒时间戳。以字符串形式发送。",
            "type": "string"
          },
          "data": {
            "type": "object",
            "properties": {
              "teamId": {
                "description": "拥有该资源的团队。",
                "type": "string"
              },
              "cloudPhoneId": {
                "description": "该事件对应的云手机。",
                "type": "string"
              },
              "reason": {
                "description": "关机原因。",
                "type": "string",
                "enum": [
                  "NORMAL",
                  "MONEY_SAVING",
                  "OTHER"
                ]
              }
            },
            "required": [
              "teamId",
              "cloudPhoneId",
              "reason"
            ]
          },
          "result": {
            "$ref": "#/components/schemas/WebhookResult"
          }
        },
        "required": [
          "eventId",
          "eventType",
          "eventTime",
          "data",
          "result"
        ]
      },
      "CloudBrowserWebhookEvent": {
        "type": "object",
        "properties": {
          "eventId": {
            "description": "唯一事件 ID。同一事件的投递重试与内部重放都复用它，因此请把它当作幂等键。",
            "type": "string"
          },
          "eventType": {
            "description": "稳定的事件名称。",
            "type": "string"
          },
          "eventTime": {
            "description": "业务最终结果发生的时间，Unix 毫秒时间戳。以字符串形式发送。",
            "type": "string"
          },
          "data": {
            "type": "object",
            "properties": {
              "teamId": {
                "description": "拥有该资源的团队。",
                "type": "string"
              },
              "cloudBrowserId": {
                "description": "该事件对应的云浏览器环境。",
                "type": "string"
              },
              "runId": {
                "description": "该事件对应的运行实例。",
                "type": "string"
              }
            },
            "required": [
              "teamId",
              "cloudBrowserId",
              "runId"
            ]
          },
          "result": {
            "$ref": "#/components/schemas/WebhookResult"
          }
        },
        "required": [
          "eventId",
          "eventType",
          "eventTime",
          "data",
          "result"
        ]
      },
      "CloudBrowserStopWebhookEvent": {
        "type": "object",
        "properties": {
          "eventId": {
            "description": "唯一事件 ID。同一事件的投递重试与内部重放都复用它，因此请把它当作幂等键。",
            "type": "string"
          },
          "eventType": {
            "description": "稳定的事件名称。",
            "type": "string"
          },
          "eventTime": {
            "description": "业务最终结果发生的时间，Unix 毫秒时间戳。以字符串形式发送。",
            "type": "string"
          },
          "data": {
            "type": "object",
            "properties": {
              "teamId": {
                "description": "拥有该资源的团队。",
                "type": "string"
              },
              "cloudBrowserId": {
                "description": "该事件对应的云浏览器环境。",
                "type": "string"
              },
              "runId": {
                "description": "该事件对应的运行实例。",
                "type": "string"
              },
              "reason": {
                "description": "运行实例停止的原因。",
                "type": "string",
                "enum": [
                  "NORMAL",
                  "MONEY_SAVING",
                  "ENERGY_SAVING",
                  "BROWSER_EXITED",
                  "OTHER"
                ]
              }
            },
            "required": [
              "teamId",
              "cloudBrowserId",
              "runId",
              "reason"
            ]
          },
          "result": {
            "$ref": "#/components/schemas/WebhookResult"
          }
        },
        "required": [
          "eventId",
          "eventType",
          "eventTime",
          "data",
          "result"
        ]
      }
    }
  },
  "servers": [
    {
      "url": "https://api.morelogin.com",
      "description": "MoreLogin 开放 API 端点"
    }
  ],
  "security": [
    {
      "Authorization": []
    }
  ]
}